﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using Microsoft.Office.Tools.Excel;
using Microsoft.VisualStudio.Tools.Applications.Runtime;
using Excel = Microsoft.Office.Interop.Excel;
using Office = Microsoft.Office.Core;
using System.Data;
using System.Windows.Forms;
using System.IO;
using System.Configuration;
using Microsoft.Win32;
using Microsoft.Office.Interop.Excel;

namespace Presentation
{
#if EXCEL

    /// <summary>
    /// Display results using Microsoft Office Excel
    /// </summary>

    public class Display : IPresentation
    {
        // Ecel object
        private Excel.Application excel;
        // Excel workbok object
        private Excel.Workbook wb;


        private int freeSheets = 0;
        private int currentSheetNo = 1;

        public Display()
        {
            excel = new Excel.Application();
            wb = excel.Workbooks.Add(Type.Missing);

            freeSheets = wb.Sheets.Count;
        }

        private void setCurrentSheet(string name)
        {

            if (currentSheetNo > freeSheets)
            {
                wb.Sheets.Add(Type.Missing, wb.Sheets[currentSheetNo-1], 1, Type.Missing);
            }

            wb.Sheets[currentSheetNo].Activate();

            wb.Sheets[currentSheetNo].Name = name + "(" + currentSheetNo.ToString() + ")";
        }

        private void makeInterior()
        {
            wb.Application.Selection.Interior.Pattern = Constants.xlSolid;
            wb.Application.Selection.Interior.PatternColorIndex = Constants.xlAutomatic;
            wb.Application.Selection.Interior.ThemeColor = XlThemeColor.xlThemeColorDark1;
            wb.Application.Selection.Interior.TintAndShade = -0.249977111117893;
            wb.Application.Selection.Interior.PatternTintAndShade = 0;
        }

        private void makeBorders()
        {
            wb.Application.Selection.Borders(XlBordersIndex.xlDiagonalDown).LineStyle = Constants.xlNone;
            wb.Application.Selection.Borders(XlBordersIndex.xlDiagonalUp).LineStyle = Constants.xlNone;

            wb.Application.Selection.Borders(XlBordersIndex.xlEdgeLeft).LineStyle = XlLineStyle.xlContinuous;
            wb.Application.Selection.Borders(XlBordersIndex.xlEdgeLeft).ColorIndex = 0;
            wb.Application.Selection.Borders(XlBordersIndex.xlEdgeLeft).TintAndShade = 0;
            wb.Application.Selection.Borders(XlBordersIndex.xlEdgeLeft).Weight = XlBorderWeight.xlThin;

            wb.Application.Selection.Borders(XlBordersIndex.xlEdgeTop).LineStyle = XlLineStyle.xlContinuous;
            wb.Application.Selection.Borders(XlBordersIndex.xlEdgeTop).ColorIndex = 0;
            wb.Application.Selection.Borders(XlBordersIndex.xlEdgeTop).TintAndShade = 0;
            wb.Application.Selection.Borders(XlBordersIndex.xlEdgeTop).Weight = XlBorderWeight.xlThin;

            wb.Application.Selection.Borders(XlBordersIndex.xlEdgeBottom).LineStyle = XlLineStyle.xlContinuous;
            wb.Application.Selection.Borders(XlBordersIndex.xlEdgeBottom).ColorIndex = 0;
            wb.Application.Selection.Borders(XlBordersIndex.xlEdgeBottom).TintAndShade = 0;
            wb.Application.Selection.Borders(XlBordersIndex.xlEdgeBottom).Weight = XlBorderWeight.xlThin;

            wb.Application.Selection.Borders(XlBordersIndex.xlEdgeRight).LineStyle = XlLineStyle.xlContinuous;
            wb.Application.Selection.Borders(XlBordersIndex.xlEdgeRight).ColorIndex = 0;
            wb.Application.Selection.Borders(XlBordersIndex.xlEdgeRight).TintAndShade = 0;
            wb.Application.Selection.Borders(XlBordersIndex.xlEdgeRight).Weight = XlBorderWeight.xlThin;

            wb.Application.Selection.Borders(XlBordersIndex.xlInsideVertical).LineStyle = XlLineStyle.xlContinuous;
            wb.Application.Selection.Borders(XlBordersIndex.xlInsideVertical).ColorIndex = 0;
            wb.Application.Selection.Borders(XlBordersIndex.xlInsideVertical).TintAndShade = 0;
            wb.Application.Selection.Borders(XlBordersIndex.xlInsideVertical).Weight = XlBorderWeight.xlThin;

            wb.Application.Selection.Borders(XlBordersIndex.xlInsideHorizontal).LineStyle = XlLineStyle.xlContinuous;
            wb.Application.Selection.Borders(XlBordersIndex.xlInsideHorizontal).ColorIndex = 0;
            wb.Application.Selection.Borders(XlBordersIndex.xlInsideHorizontal).TintAndShade = 0;
            wb.Application.Selection.Borders(XlBordersIndex.xlInsideHorizontal).Weight = XlBorderWeight.xlThin;
        }

        private void write2Excel(object data, string[] colNames, int rows, int cols)
        {
            int row = 1;
            string firstCol = "A";

            int colNo = 0;

            string cellName = string.Empty;
            string c = string.Empty;

            foreach (string colName in colNames)
            {
                int ord = (int)Convert.ToChar(firstCol) + colNo;

                c = ((char)(ord)).ToString();

                cellName = c + row.ToString();

                wb.Sheets[currentSheetNo].Range(cellName).Select();
                wb.Application.ActiveCell.Formula = colName;

                colNo++;
            }

            wb.Sheets[currentSheetNo].Range("A1:" + cellName).Select();

            makeInterior();

            row++;

            Array d = data as Array;

            for (int x = 0; x < rows; x++)
            {
                for (int y = 0; y < cols; y++)
                {
                    int ord = (int)Convert.ToChar(firstCol) + y;

                    c = ((char)(ord)).ToString();

                    cellName = c + row.ToString();

                    wb.Sheets[currentSheetNo].Range(cellName).Select();
                    wb.Application.ActiveCell.Formula = d.GetValue(new int[] { x, y });
                }

                row++;
            }

            wb.Sheets[currentSheetNo].Range("A1:" + cellName).Select();

            makeBorders();

            wb.Sheets[currentSheetNo].Range("A1").Select();

        }

        private void getData(object data,string[] colNames)
        {
            Type t = data.GetType();

            PropertyInfo[] propertyInfos = t.GetProperties();

            int cols = 0, dataLength = 0, rows = 0;

            if (t.IsArray)
            {

                foreach (PropertyInfo p in propertyInfos)
                {
                    if (p.Name == "Rank")
                    {
                        cols = (int)p.GetValue(data, null);
                    }

                    if (p.Name == "Length")
                    {
                        dataLength = (int)p.GetValue(data, null);
                    }
                }

                rows = dataLength / cols;

                write2Excel(data, colNames, rows, cols);
            }
        }

        public void DisplayRaw(object data, string name, string[] colNames)
        {
            setCurrentSheet(name);

            excel.Visible = false;

            getData(data, colNames);

            excel.Visible = true;

            currentSheetNo++;
        }

        public void DisplayGraph(object data, string name, string[] colNames)
        {
            DisplayRaw(data, name, colNames);
        }
    }
#else
#endif
}

